home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / source / snapshot / snapshot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-12  |  11.0 KB  |  411 lines

  1. /* SnapShot.c
  2.  
  3.      (C) Copyright Microsoft Corp. 1991.  All rights reserved.
  4.  
  5.      You have a royalty-free right to use, modify, reproduce and 
  6.      distribute the Sample Files (and/or any modified version) in 
  7.      any way you find useful, provided that you agree that 
  8.      Microsoft has no warranty obligations or liability for any 
  9.      Sample Application Files which are modified. 
  10.  
  11.  */
  12.  
  13. // the correct definition...
  14. unsigned int    far pascal GetSystemPaletteUse(unsigned int);
  15.  
  16.  
  17. // see the WDB sample code for debugging ideas.
  18. #define dprintf    
  19.  
  20.  
  21. #include <windows.h>
  22. #include "SnapShot.h"
  23.  
  24.  
  25. /* constants */
  26. #define APPNAME "SnapShot"
  27.  
  28.  
  29. /* globals */
  30. char    gszAppName[] = APPNAME;        // for title bar etc.
  31.  
  32. HANDLE        ghInst;                // program instance handle
  33.  
  34. int    gcxScreen, gcyScreen;        // screen size
  35.  
  36.  
  37. /* prototypes */
  38. BOOL FAR PASCAL _export AppAbout ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  39. BOOL PASCAL AppInit(HANDLE hInst, HANDLE hPrev);
  40. int    PASCAL WinMain(HANDLE hInst, HANDLE hPrev, LPSTR lpszCmdLine, int iCmdShow);
  41. LONG FAR PASCAL _export AppWndProc(HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam);
  42. HPALETTE NEAR PASCAL CreateSystemPalette(HDC hdcScreen);
  43. void NEAR PASCAL SnapShot(HWND hwnd);
  44.  
  45.  
  46.  
  47. /* AppAbout(hDlg, uiMessage, wParam, lParam)
  48.  *
  49.  * This function handles messages belonging to the "About" dialog box.
  50.  * The only message that it looks for is WM_COMMAND, indicating the use
  51.  * has pressed the "OK" button.  When this happens, it takes down
  52.  * the dialog box.
  53.  */
  54. BOOL FAR PASCAL _export           // TRUE iff message has been processed
  55. AppAbout ( HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
  56. {
  57.     char ach[128];
  58.     
  59.     switch (uiMessage)
  60.     {
  61.     case WM_INITDIALOG:
  62.         // nothing to initialize 
  63.         wsprintf(ach,"Compiled: %s %s",(LPSTR)__DATE__,(LPSTR)__TIME__);
  64.         SetDlgItemText(hwnd,IDD_TEXT,ach);
  65.         break;
  66.  
  67.     case WM_COMMAND:
  68.         switch(wParam)
  69.         {
  70.         case IDOK:
  71.             EndDialog(hwnd, TRUE);
  72.             break;
  73.             
  74.         default:
  75.             return FALSE;
  76.         }
  77.         break;
  78.         
  79.     default:
  80.         return FALSE;
  81.     }
  82.     return TRUE;
  83. }
  84.  
  85.  
  86. /* AppInit(hInst, hPrev)
  87.  *
  88.  * This is called when the application is first loaded into memory.
  89.  * It performs all initialization that doesn't need to be done once
  90.  * per instance.
  91.  */
  92. BOOL PASCAL            // returns TRUE iff successful
  93. AppInit(HANDLE hInst, HANDLE hPrev)
  94. {
  95.     WNDCLASS    wndclass;
  96.  
  97. #ifdef DEBUG
  98. //    wpfGetDebugLevel(gszAppName);
  99. #endif
  100.  
  101.     if (!hPrev)
  102.     {
  103. /* Register a class for the main application window */
  104.         wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  105.         wndclass.hIcon = LoadIcon(hInst, "AppIcon");
  106.         wndclass.lpszMenuName = "AppMenu";
  107.         wndclass.lpszClassName = gszAppName;
  108.         wndclass.hbrBackground = (HBRUSH) COLOR_WINDOW + 1;
  109.         wndclass.hInstance = hInst;
  110.         wndclass.style = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW;
  111.         wndclass.lpfnWndProc = AppWndProc;
  112.         wndclass.cbWndExtra = 0;
  113.         wndclass.cbClsExtra = 0;
  114.  
  115.         if (!RegisterClass(&wndclass))
  116.             return FALSE;
  117.     }
  118.  
  119.     return TRUE;
  120. }
  121.  
  122.  
  123. /* WinMain(hInst, hPrev, lpszCmdLine, cmdShow)
  124.  * 
  125.  * The main procedure for the App.  After initializing, it just goes
  126.  * into a message-processing loop until it gets a WM_QUIT message
  127.  * (meaning the app was closed).
  128.  */
  129. int    PASCAL            // returns exit code specified in WM_QUIT
  130. WinMain(HANDLE hInst, HANDLE hPrev, LPSTR lpszCmdLine, int iCmdShow)
  131. {
  132.     MSG        msg;        // message from queue
  133.  
  134.     HWND        hwnd;        // handle to app's window
  135.  
  136.     HMENU        hmenuSystem;    // system menu
  137.  
  138.     RECT        rc;
  139.  
  140. /* save instance handle for dialog boxes */
  141.     ghInst = hInst;
  142.  
  143. /* call initialization procedure */
  144.     if (!AppInit(hInst, hPrev))
  145.         return FALSE;
  146.  
  147. /* define the app window style */
  148. #define APPWINDOWSTYLE        \
  149.         (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU)
  150.  
  151. /* get the screen size */
  152.     gcxScreen = GetSystemMetrics(SM_CXSCREEN);
  153.     gcyScreen = GetSystemMetrics(SM_CYSCREEN);
  154.  
  155. /* size the app window to just fit around the edit window */
  156.     rc.left = 0;
  157.     rc.right = gcxScreen / 4;
  158.     rc.top = 0;
  159.     rc.bottom = 0;
  160.     AdjustWindowRect(&rc, APPWINDOWSTYLE, TRUE);
  161.  
  162. /* create the application's window */
  163.     hwnd = CreateWindow
  164.         (
  165.     gszAppName,         // window class
  166.         gszAppName,         // window caption
  167.         APPWINDOWSTYLE,         // window style
  168.             gcxScreen - (rc.right - rc.left),     // initial x-coord
  169.             gcyScreen - (rc.bottom - rc.top),     // initial y-coord
  170.         rc.right - rc.left,             // initial width
  171.         rc.bottom - rc.top,             // initial height
  172.         NULL,             // parent window handle
  173.         NULL,             // window menu handle
  174.         hInst,             // program instance handle
  175.         NULL            // create parameters
  176.         );
  177.     ShowWindow(hwnd, iCmdShow);
  178.  
  179. /* append "Show Clipboard" and "About" menu item to system menu */
  180.     hmenuSystem = GetSystemMenu(hwnd, FALSE);
  181.     AppendMenu(hmenuSystem, MF_SEPARATOR, 0, NULL);
  182.     AppendMenu(hmenuSystem, MF_STRING, IDM_SHOWCLIP, "S&how Clipboard");
  183.     AppendMenu(hmenuSystem, MF_STRING, IDM_ABOUT, "&About " APPNAME "...");
  184.  
  185. /* get messages from event queue and dispatch them */
  186.     while (GetMessage(&msg, NULL, 0, 0))
  187.     {
  188.         TranslateMessage(&msg);
  189.         DispatchMessage(&msg);
  190.     }
  191.  
  192.     return msg.wParam;
  193. }
  194.  
  195.  
  196. /* AppWndProc(hwnd, uiMessage, wParam, lParam)
  197.  * 
  198.  * The window proc for the app's main window.  This processes all
  199.  * of the parent window's messages.
  200.  */
  201. LONG FAR PASCAL _export        // returns 0 iff processed message
  202. AppWndProc(HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
  203. {
  204.     FARPROC        fpfn;
  205.     PAINTSTRUCT    ps;
  206.  
  207.     switch (uiMessage)
  208.     {
  209.  
  210.     case WM_COMMAND:
  211.  
  212.         switch (wParam)
  213.         {
  214.  
  215.         case IDM_NOW:
  216.  
  217.             ShowWindow(hwnd, SW_HIDE);
  218.             SnapShot(hwnd);
  219.             ShowWindow(hwnd, SW_NORMAL);
  220.             break;
  221.  
  222.         case IDM_5SEC:
  223.  
  224.             SetTimer(hwnd, 1, 5000, NULL);
  225.             ShowWindow(hwnd, SW_HIDE);
  226.             break;
  227.  
  228.         }
  229.         return 0L;
  230.  
  231.     case WM_TIMER:
  232.  
  233.         KillTimer(hwnd, 1);
  234.         MessageBeep(0);
  235.         SnapShot(hwnd);
  236.         MessageBeep(0);
  237.         ShowWindow(hwnd, SW_NORMAL);
  238.         break;
  239.  
  240.     case WM_SYSCOMMAND:
  241.  
  242.         switch (wParam)
  243.         {
  244.  
  245.         case IDM_SHOWCLIP:
  246.  
  247.             WinExec("CLIPBRD.EXE", SW_NORMAL);
  248.             break;
  249.  
  250.         case IDM_ABOUT:
  251.  
  252.         /* request to display "About" dialog box */
  253.         fpfn = MakeProcInstance((FARPROC) AppAbout, ghInst);
  254.         DialogBox(ghInst, MAKEINTRESOURCE(ABOUTBOX),
  255.             hwnd, fpfn);
  256.         FreeProcInstance(fpfn);
  257.         break;
  258.  
  259.         }
  260.         break;
  261.  
  262.     case WM_DESTROY:
  263.  
  264.         /* exit this program */
  265.         PostQuitMessage(0);
  266.         break;
  267.  
  268.     }
  269.  
  270.     return DefWindowProc(hwnd, uiMessage, wParam, lParam);
  271. }
  272.  
  273.  
  274. /* hpal = CreateSystemPalette(hdcScreen)
  275.  *
  276.  * Return a palette which represents the system palette.  By selecting this
  277.  * palette into a screen DC and realizing the palette, you can BitBlt from
  278.  * the screen DC to a memory bitmap to get a correct screen shot.
  279.  *
  280.  * <hdcScreen> is a DC onto the screen.
  281.  *
  282.  * On error (e.g. out of memory), NULL is returned.
  283.  */
  284. HPALETTE NEAR PASCAL
  285. CreateSystemPalette(HDC hdcScreen)        // DC onto the screen
  286.  
  287. {
  288.     int    iSizePalette;        // size of entire palette
  289.  
  290.     int    iFixedPalette;        // number of reserved colors
  291.  
  292.     NPLOGPALETTE    pLogPal = NULL;
  293.     HPALETTE    hpal = NULL;
  294.     int    i;
  295.  
  296. /* calculate <iSizePalette> and <iFixedPalette> */
  297.     if (GetSystemPaletteUse(hdcScreen) == SYSPAL_STATIC)
  298.         iFixedPalette = GetDeviceCaps(hdcScreen, NUMCOLORS);
  299.     else
  300.         iFixedPalette = 2;
  301.  
  302.     iSizePalette = GetDeviceCaps(hdcScreen, SIZEPALETTE);
  303.     dprintf("CreateSystemPalette: iFixedPalette=%d, iSizePalette=%d\n",
  304.         iFixedPalette, iSizePalette);
  305.  
  306. /* create a logical palette containing the system colors;
  307.      * this palette has all entries except fixed (system) colors
  308.      * flagged as PC_NOCOLLAPSE
  309.      */
  310.     pLogPal = (NPLOGPALETTE) LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE)
  311.          + iSizePalette * sizeof(PALETTEENTRY));
  312.  
  313.     dprintf("CreateSystemPalette: pLogPal=0x%04x\n", pLogPal);
  314.  
  315.     if (pLogPal == NULL)
  316.         goto CreateSystemPalette_ERROR;
  317.  
  318.     pLogPal->palVersion = 0x300;
  319.     pLogPal->palNumEntries = iSizePalette;
  320.     GetSystemPaletteEntries(hdcScreen, 0, iSizePalette,
  321.         pLogPal->palPalEntry);
  322.  
  323.     for (i = 0; i < iSizePalette; i++)
  324.         pLogPal->palPalEntry[i].peFlags = 
  325.             ((i >= iFixedPalette / 2) && 
  326.             (i < iSizePalette - iFixedPalette / 2))
  327.          ? PC_NOCOLLAPSE : 0;
  328.  
  329.     hpal = CreatePalette((LPLOGPALETTE) pLogPal);
  330.     dprintf("CreateSystemPalette: hpal=0x%04x\n", hpal);
  331.  
  332. CreateSystemPalette_ERROR:
  333.  
  334.     if (pLogPal != NULL)
  335.         LocalFree((HANDLE) pLogPal);
  336.  
  337.     return hpal;
  338. }
  339.  
  340.  
  341. void NEAR PASCAL
  342. SnapShot(HWND hwnd)            // owner of clipboard data
  343. {
  344.     HDC        hdcScreen = NULL;
  345.     HBITMAP        hbitmap = NULL;
  346.     HDC        hdcBitmap = NULL;
  347.     HPALETTE    hpal = NULL;
  348.     HPALETTE    hpalScreenOld;
  349.  
  350.     hdcScreen = GetDC(NULL);
  351.     dprintf("SnapShot: hdcScreen=0x%04x\n", hdcScreen);
  352.  
  353. /* create a memory bitmap */
  354.     hdcBitmap = CreateCompatibleDC(hdcScreen);
  355.     hbitmap = CreateCompatibleBitmap(hdcScreen, gcxScreen, gcyScreen);
  356.     dprintf("SnapShot: hdcBitmap=0x%04x, hbitmap=0x%04x\n",
  357.         hdcBitmap, hbitmap);
  358.     if (hbitmap == NULL)
  359.     {
  360. //        Error(IDS_OUTOFMEMORY);
  361.         goto SnapShot_ERROR;
  362.     }
  363.     SelectObject(hdcBitmap, hbitmap);
  364.  
  365. /* create a palette corresponding to the current physical palette */
  366.     hpal = CreateSystemPalette(hdcScreen);
  367.     if (hpal == NULL)
  368.     {
  369. //        Error1(IDS_INTERNALERROR, __LINE__);
  370.         goto SnapShot_ERROR;
  371.     }
  372.  
  373. /* copy the screen to the bitmap */
  374.     hpalScreenOld = SelectPalette(hdcScreen, hpal, FALSE);
  375.     RealizePalette(hdcScreen);
  376.     BitBlt(hdcBitmap, 0, 0, gcxScreen, gcyScreen, hdcScreen, 0, 0, SRCCOPY);
  377.     SelectPalette(hdcScreen, hpalScreenOld, FALSE);
  378.  
  379. /* give the bitmap and palette to the clipboard */
  380.     if (OpenClipboard(hwnd))
  381.     {
  382.         EmptyClipboard();
  383.         SetClipboardData(CF_BITMAP, hbitmap);
  384.         SetClipboardData(CF_PALETTE, hpal);
  385.         CloseClipboard();
  386.         hbitmap = NULL;        // bitmap is now owned by clipboard
  387.  
  388.         hpal = NULL;        // palette is now owned by clipboard
  389.     }
  390.     else
  391.         dprintf("SnapShot: can't open clipboard\n");
  392.  
  393. /* fall through */
  394.  
  395. SnapShot_ERROR:
  396.  
  397. /* clean up */
  398.     if (hdcBitmap != NULL)
  399.         DeleteDC(hdcBitmap), hdcBitmap = NULL;
  400.     if (hbitmap != NULL)
  401.         DeleteObject(hbitmap), hbitmap = NULL;
  402.     if (hpal != NULL)
  403.         DeleteObject(hpal), hpal = NULL;
  404.     if (hdcScreen != NULL)
  405.         ReleaseDC(NULL, hdcScreen), hdcScreen = NULL;
  406.  
  407.     dprintf("SnapShot: done.\n");
  408. }
  409.  
  410.  
  411.